package com.xh.bussiness.tiku.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xh.bussiness.tiku.bean.dto.BookChapterDto;
import com.xh.bussiness.tiku.bean.request.BookChapterRequest;
import com.xh.bussiness.tiku.constant.BookChapterConstant;
import com.xh.bussiness.tiku.dao.BookChapterMapper;
import com.xh.bussiness.tiku.model.BookChapter;
import com.xh.bussiness.tiku.model.BookVersion;
import com.xh.bussiness.tiku.model.ChapterKnowledge;
import com.xh.bussiness.tiku.model.Knowledge;
import com.xh.bussiness.tiku.service.IBookChapterService;
import com.xh.bussiness.tiku.service.IBookVersionService;
import com.xh.bussiness.tiku.service.IChapterKnowledgeService;
import com.xh.bussiness.tiku.service.IKnowledgeService;
import com.xh.core.bean.XhPage;
import com.xh.core.service.IElasticSearchService;
import com.xh.core.service.impl.BaseServiceImpl;
import com.xh.core.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 教材章节 服务实现类
 * </p>
 *
 * @author daiwei
 * @since 2019-01-14
 */
@Service
public class BookChapterServiceImpl extends BaseServiceImpl<BookChapterMapper, BookChapter> implements IBookChapterService {

    public static final Logger log = LoggerFactory.getLogger(BookChapterServiceImpl.class);

    @Autowired
    private IKnowledgeService knowledgeService;
    @Autowired
    private IChapterKnowledgeService chapterKnowledgeService;
    @Autowired
    private IBookVersionService bookVersionService;
    @Autowired
    private IElasticSearchService elasticSearchService;

    @Override
    public XhPage queryBookChapterPage(XhPage page, BookChapterRequest bean) {
        QueryWrapper qw = new QueryWrapper<BookChapter>();
        //拼装条件
        qw = prepareParams(bean, qw);

        return (XhPage) this.selectPage(page, qw, BookChapterDto.class);
    }

    @Override
    public List queryBookChapter(BookChapterRequest bean) {
        QueryWrapper qw = new QueryWrapper<BookChapter>();
        //拼装条件
        qw = prepareParams(bean, qw);

        return this.selectList(qw, BookChapterDto.class);
    }


    /**
     * 准备条件
     *
     * @param bean
     * @param qw
     */
    private QueryWrapper prepareParams(BookChapterRequest bean, QueryWrapper qw) {
        if (bean.getIds() != null && bean.getIds().length > 0) {
            qw.in("id", bean.getIds());
        }
        if (!StringUtils.isEmpty(bean.getBookVersionId())) {
            qw.eq("book_version_id", bean.getBookVersionId());
        }
        if (!StringUtils.isEmpty(bean.getParentId())) {
            qw.eq("parent_id", bean.getParentId());
        }
        if (!StringUtils.isEmpty(bean.getName())) {
            qw.like("name", bean.getName());
        }
        return qw;
    }


    @Override
    public List<BookChapter> queryBookChapterKnowledgeTree(String bookId) {
        QueryWrapper<BookChapter> qw = new QueryWrapper<BookChapter>();
        qw.eq("book_version_id", bookId);
        qw.orderByAsc("sort_index");
        List<BookChapter> all = super.queryByCondition(qw);
        List<BookChapter> roots = getRoots(all);
        creatChapterKnowledgeTree(roots, all);
        return roots;
    }

    @Override
    public List<BookChapter> queryTree(String bookId) {
        QueryWrapper<BookChapter> qw = new QueryWrapper<BookChapter>();
        qw.eq("book_version_id", bookId);
        qw.orderByAsc("sort_index");
        List<BookChapter> all = super.queryByCondition(qw);
        List<BookChapter> roots = getRoots(all);
        creatTree(roots, all);
        return roots;
    }

    private List<BookChapter> getRoots(List<BookChapter> all) {
        List<BookChapter> roots = new ArrayList<BookChapter>();
        all.forEach(b -> {
            if (StringUtils.isEmpty(b.getParentId()) || "0".equals(b.getParentId())) {
                roots.add(b);
            }
        });
        return roots;
    }

    private void creatChapterKnowledgeTree(List<BookChapter> roots, List<BookChapter> all) {
        for (BookChapter root : roots) {
            List<BookChapter> childs = new ArrayList<BookChapter>();
            for (BookChapter chapter : all) {
                if (chapter.getParentId() != null && chapter.getParentId().equals(root.getId())) {
                    childs.add(chapter);
                } else {
                    //为空则查询考点数据
                    List<Knowledge> knowledges = knowledgeService.queryKnowledgeByChapterId(chapter.getId(), chapter.getName());
                    if (!CollectionUtils.isEmpty(knowledges)) {
                        chapter.setKnowledgeList(knowledges);
                    }
                }
            }
            root.setChilds(childs);
            creatChapterKnowledgeTree(childs, all);
        }
    }

    private void creatTree(List<BookChapter> roots, List<BookChapter> all) {
        for (BookChapter root : roots) {
            List<BookChapter> childs = new ArrayList<BookChapter>();
            for (BookChapter chapter : all) {
                if (chapter.getParentId() != null && chapter.getParentId().equals(root.getId())) {
                    childs.add(chapter);
                }
                if (!childs.isEmpty()) {
                    root.setChilds(childs);
                }
                creatTree(childs, all);
            }
        }
    }


    @Override
    public void initParentPath() {
        QueryWrapper queryWrapper = new QueryWrapper();
        //	queryWrapper.in("id", "7c8a7741-45be-4016-9569-67e40b821d69","581be0c3-e629-4f1b-b065-f8dd2d9305db");
        queryWrapper.isNull("parent_id");
        List<BookChapter> roots = this.getDao().selectList(queryWrapper);

        for (BookChapter root : roots) {
            getChildren(root, null, null, root.getId());
        }
        // 清缓存
//        deleteCache();
    }

    @Override
    public void initBookChapterKnowledgeRelation(List<BookChapter> bookChapters) {
        if (CollectionUtils.isEmpty(bookChapters)) {
            return;
        }
        List<ChapterKnowledge> chapterKnowledges = new ArrayList<>();
        for (BookChapter bookChapter : bookChapters) {
            if (!CollectionUtils.isEmpty(bookChapter.getKnowledgeList())) {
                for (Knowledge knowledge : bookChapter.getKnowledgeList()) {
                    Knowledge knowledgeResult = queryByParams(knowledge.getSubject(), knowledge.getNo(), knowledge.getName());
                    if (knowledgeResult != null) {
                        ChapterKnowledge chapterKnowledge = new ChapterKnowledge();
                        chapterKnowledge.setChapterId(bookChapter.getId());
                        chapterKnowledge.setKnowledgeId(knowledgeResult.getId());
                        chapterKnowledges.add(chapterKnowledge);
                    }
                }
            }
        }
        if (!CollectionUtils.isEmpty(chapterKnowledges)) {
            chapterKnowledgeService.batchInsert(chapterKnowledges);
        }
        // 清缓存
//        deleteCache();
    }

    @Override
    public boolean addBookChapter(BookChapterDto bookChapterDto) {
        if (StringUtils.isEmpty(bookChapterDto.getBookVersionId())) {
            return false;
        }
        //教材版本
        BookVersion bookVersion = bookVersionService.getById(bookChapterDto.getBookVersionId());
        if (bookVersion == null) {
            return false;
        }
        //获取当前节点最大排序节点
        BookChapter maxBookChapter = this.getMaxSortIndexBookChapterByBookVersionId(bookChapterDto.getBookVersionId(), bookChapterDto.getParentId());
        //序号
        Integer sortIndex = maxBookChapter == null ? 1 : maxBookChapter.getSortIndex() + 1;
        BookChapter bookChapter = new BookChapter();
        bookChapter.setBookVersionId(bookChapterDto.getBookVersionId());
        bookChapter.setName(bookChapterDto.getName());
        bookChapter.setSortIndex(sortIndex);
        this.insert(bookChapter);
        if (StringUtils.isEmpty(bookChapterDto.getParentId())) {
            //添加根节点
            bookChapter.setPath(String.format("#%s#", bookChapter.getId()));
            bookChapter.setPathName(String.format("#%s#", bookChapter.getName()));
        } else {
            //添加子节点
            BookChapter parentBookChapter = this.getById(bookChapterDto.getParentId());
            if (parentBookChapter == null) {
                log.error(String.format("addBookChapter parentBookChapter not find by parentId:%s", bookChapterDto.getParentId()));
                return false;
            }
            bookChapter.setParentId(bookChapterDto.getParentId());
            bookChapter.setParentPathId(parentBookChapter.getPath());
            bookChapter.setParentPathName(parentBookChapter.getPathName());
            bookChapter.setPath(String.format("%s%s#", parentBookChapter.getPath(), bookChapter.getId()));
            bookChapter.setPathName(String.format("%s%s#", parentBookChapter.getPathName(), bookChapter.getName()));
        }
        this.update(bookChapter);
        // 清缓存
        deleteCacheBySubjectCode(bookVersion.getSubject());
        return true;
    }

    @Override
    public boolean moveUpOrDownBookChapter(String bookChapterId, Integer moveType) {
        if (StringUtils.isEmpty(bookChapterId) || moveType == null) {
            log.error("moveUpOrDownBookChapter params error");
            return false;
        }
        BookChapter bookChapter = this.getById(bookChapterId);
        if (bookChapter == null) {
            log.error(String.format("moveUpOrDownBookChapter current node is null by id:%s", bookChapterId));
            return false;
        }
        //相邻节点
        BookChapter siblingsNode = getUpOrDownBookChapter(bookChapter.getBookVersionId(), bookChapter.getParentId(), bookChapter.getSortIndex(), moveType);
        if (siblingsNode != null) {
            Integer oldSortIndex = bookChapter.getSortIndex();
            bookChapter.setSortIndex(siblingsNode.getSortIndex());
            siblingsNode.setSortIndex(oldSortIndex);
            //交换排序
            this.update(bookChapter);
            this.update(siblingsNode);
        }
        BookVersion bookVersion = bookVersionService.getById(bookChapter.getBookVersionId());
        // 清缓存
        deleteCacheBySubjectCode(bookVersion.getSubject());
        return true;
    }

    /**
     * 根据教材版本获取最大排序章节
     *
     * @param bookVersionId
     * @return
     */
    private BookChapter getMaxSortIndexBookChapterByBookVersionId(String bookVersionId, String parentId) {
        QueryWrapper<BookVersion> qw = new QueryWrapper<>();
        qw.eq("book_version_id", bookVersionId);
        if (StringUtils.isEmpty(parentId)) {
            qw.isNull("parent_id");
        } else {
            qw.eq("parent_id", parentId);
        }
        qw.orderByDesc("sort_index");
        return this.selectFirst(qw);
    }

    /**
     * 获取当前节点上面或下面的一个节点
     *
     * @param bookVersionId
     * @param parentId
     * @param sortIndex
     * @param moveType
     * @return
     */
    private BookChapter getUpOrDownBookChapter(String bookVersionId, String parentId, Integer sortIndex, Integer moveType) {
        QueryWrapper<BookChapter> qw = new QueryWrapper<>();
        qw.eq("book_version_id", bookVersionId);
        if (StringUtils.isEmpty(parentId)) {
            qw.isNull("parent_id");
        } else {
            qw.eq("parent_id", parentId);
        }
        if (moveType.equals(1)) {
            //上移
            qw.lt("sort_index", sortIndex);
            qw.orderByDesc("sort_index");
        } else {
            qw.gt("sort_index", sortIndex);
            qw.orderByAsc("sort_index");
        }
        return this.selectFirst(qw);
    }

    public Knowledge queryByParams(String subject, String no, String name) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("no", no);
        queryWrapper.eq("subject", subject);
        queryWrapper.eq("name", name);

        List<Knowledge> knowledgeList = knowledgeService.selectList(queryWrapper, Knowledge.class);
        if (!CollectionUtils.isEmpty(knowledgeList)) {
            return knowledgeList.get(0);
        }
        return null;
    }

    void getChildren(BookChapter parent, String parentPathId, String parentPathName, String parentId) {
        if (!StringUtils.isEmpty(parentPathId)) {
            parent.setParentPathId(parentPathId + "#");
            parent.setParentPathName(parentPathName + "#");

            this.update(parent);
        }

        System.out.println(JSON.toJSON(parent));
        QueryWrapper childWrapper = new QueryWrapper();
        childWrapper.eq("parent_id", parentId);

        List<BookChapter> children = this.getDao().selectList(childWrapper);
        if (!CollectionUtils.isEmpty(children)) {
            parentPathId = parentPathId == null ? "" : parentPathId;
            parentPathId += "#" + parent.getId();
            parentPathName = parentPathName == null ? "" : parentPathName;
            parentPathName += "#" + parent.getName();
            for (BookChapter child : children) {
                getChildren(child, parentPathId, parentPathName, child.getId());
            }
        }
    }

    @Override
    public void truncateTable() {
        this.dao.truncateTable();
        // 清缓存
//        deleteCache();
    }

    @Override
    public boolean delete(Serializable id) {
        BookChapter bookChapter = super.getById(id);
        boolean result = super.delete(id);
        // 清缓存
        BookVersion bookVersion = bookVersionService.getById(bookChapter.getBookVersionId());
        deleteCacheBySubjectCode(bookVersion.getSubject());
        return result;
    }

    @Override
    public boolean batchDelete(Serializable[] ids) {
        if (ids == null || ids.length == 0) {
            return true;
        }
        BookChapter bookChapter = super.getById(ids[0]);
        boolean result = super.batchDelete(ids);
        // 清缓存
        BookVersion bookVersion = bookVersionService.getById(bookChapter.getBookVersionId());
        deleteCacheBySubjectCode(bookVersion.getSubject());
        return result;
    }

//    // 清缓存
//    private void deleteCache(Serializable bookChapterId) {
//        if (bookChapterId == null) {
//            return;
//        }
//        String subject = this.dao.getSubjectByBookChapterId(bookChapterId);
//        if (subject == null) {
//            return;
//        }
//        elasticSearchService.deleteDocument(subject, BookChapterConstant.BOOK_CHAPTER_TREE_INDEX, BookChapterConstant.BOOK_CHAPTER_TREE_TYPE);
//    }

    @Override
    public BookChapterDto saveOrUpate(BookChapterDto bookChapterDto) {
        if (StringUtils.isEmpty(bookChapterDto.getId())) {
            addBookChapter(bookChapterDto);
        } else {
            BookChapter bookChapter = super.getById(bookChapterDto.getId());
            bookChapter.setName(bookChapterDto.getName());
            super.update(bookChapter);
            BookVersion bookVersion = bookVersionService.getById(bookChapter.getBookVersionId());
            deleteCacheBySubjectCode(bookVersion.getSubject());
        }
        return bookChapterDto;
    }

    @Override
    public void deleteCacheBySubjectCode(String subjectCode) {
        if (StringUtils.isEmpty(subjectCode)) {
            return;
        }
        elasticSearchService.deleteIndex(BookChapterConstant.BOOK_CHAPTER_TREE_INDEX_PREFIX + subjectCode);
    }

    // 清缓存
//    private void deleteCache() {
//        elasticSearchService.deleteIndex(BookChapterConstant.BOOK_CHAPTER_TREE_INDEX);
//    }

}
